import Watcher from "./observer/watcher";
import { patch } from "./vdom/patch";
import { logger } from "./utils/index";

export function lifecycleMixin(Vue) {
	// 渲染更新页面
	Vue.prototype._update = function (vNode) {
		const vm = this;
		// 解析虚拟dom生成真实dom并且替换掉$el
		vm.$el = patch(vm.$el, vNode);
	};
}

// 挂载组件
export function mountComponent(vm, el) {
	// 调用挂载前的hook
	callHook(vm, "beforeMount");
	logger.info("解析模板,开始渲染页面");
	// 挂上真实dom
	vm.$el = el;
	// Watcher 用来渲染
	// vm._render 通过解析的render方法,生成虚拟dom _c _v _s
	// vm._update 通过虚拟dom创建真实dom
	let firstRender = true; // 是不是第一次渲染
	const updateComponent = () => {
		// 首次渲染或者更新视图
		vm._update(vm._render());
		if (firstRender) {
			logger.info("视图初始化渲染完成");
			firstRender = false;
		} else {
			logger.info("视图更新渲染完成");
		}
	};
	// 渲染watcher,每个组件都有一个
	new Watcher(vm, updateComponent, () => {}, true); // true表示它是一个渲染watcher
	// 调用挂载好后的hook
	callHook(vm, "mounted");
}

// 调用对应的生命周期
export function callHook(vm, hook) {
	const handles = vm.$options[hook];
	if (handles) {
		// 按顺序掉用对应的函数,this指向对应的实例
		handles.forEach((handle) => {
			handle.call(vm);
			logger.warn(`执行了实例的${hook}方法`);
		});
	}
}
